home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 49 / Amiga Format CD49 (2000-01-17)(Future Publishing)(GB)(Track 1 of 3)[!][issue 2000-02].iso / -serious- / graphics / gnuplot / gnuplot-3.7.1src / gnuplot-3.7.1 / docs / xref.c < prev    next >
C/C++ Source or Header  |  1999-11-29  |  9KB  |  338 lines

  1. /*
  2.  * $Id: x   if (pormat, l/10/19 13:19:18 lhecking Exp $
  3.  *
  4.  */
  5.  
  6. /* GNUPLOT - xref.c */
  7.  
  8. /*[
  9.  * Copyright 1986 - 1993, 1998   Thomas Williams, Colin Kelley
  10.  *
  11.  * Permission to use, copy, and distribute this software and its
  12.  * documentation for any purpose with or without fee is hereby granted,
  13.  * provided that the above copyright notice appear in all copies and
  14.  * that both that copyright notice and this permission notice appear
  15.  * in supporting documentation.
  16.  *
  17.  * Permission to modify the software is granted, but not the right to
  18.  * distribute the complete modified source code.  Modifications are to
  19.  * be distributed as patches to the released version.  Permission to
  20.  * distribute binaries produced by compiling modified sources is granted,
  21.  * provided you
  22.  *   1. distribute the corresponding source modifications from the
  23.  *    released version in the form of a patch file along with the binaries,
  24.  *   2. add special version identification to distinguish your version
  25.  *    in addition to the base release version number,
  26.  *   3. provide your name and address as the primary contact for the
  27.  *    support of your modified version, and
  28.  *   4. retain our contact information in regard to use of the base
  29.  *    software.
  30.  * Permission to distribute the released version of the source code along
  31.  * with corresponding source modifications in the form of a patch file is
  32.  * granted with same provisions 2 through 4 for binary distributions.
  33.  *
  34.  * This software is provided "as is" without express or implied warranty
  35.  * to the extent permitted by applicable law.
  36. ]*/
  37.  
  38. /*
  39.  * this file is used by doc2ipf, doc2html, doc2rtf and doc2info
  40.  *
  41.  * MUST be included after termdoc.c (since termdoc.c redefines fgets() )
  42.  *
  43.  * it contains functions needed to handle xrefs, most of them from
  44.  *     doc2rtf (most likely) by Maurice Castro
  45.  *  or doc2ipf by Roger Fearick
  46.  *  or doc2html by Russel Lang
  47.  *
  48.  * I have modified the functions a little to make them more flexible 
  49.  * (lookup returns list instead of list->line) or let them work with all
  50.  * four programs (adding three parameters to refs).
  51.  *
  52.  * I switched the search order of lookup. Makes more sense to me
  53.  *
  54.  * Stefan Bodewig 1/29/1996
  55.  */
  56.  
  57. #ifdef HAVE_CONFIG_H
  58. # include "config.h"
  59. #endif
  60.  
  61. #define DOCS_XREF_MAIN
  62.  
  63. #include "ansichek.h"
  64. #include "stdfn.h"
  65. #include "doc2x.h"
  66. #include "xref.h"
  67.  
  68. struct LIST *list = NULL;
  69. struct LIST *head = NULL;
  70.  
  71. struct LIST *keylist = NULL;
  72. struct LIST *keyhead = NULL;
  73.  
  74. int maxlevel = 0;        /* how deep are the topics nested? */
  75. int listitems = 0;        /* number of topics */
  76.  
  77. /* for debugging (invoke from gdb !) */
  78. void dump_list()
  79. {
  80.     struct LIST *element = head;
  81.     while (element) {
  82.     fprintf(stderr, "%p level %d, line %d, \"%s\"\n", element, element->level, element->line, element->string);
  83.     element = element->next;
  84.     }
  85. }
  86.  
  87.  
  88. #ifdef PROTOTYPES
  89. void *xmalloc(size_t size)
  90. {
  91.     void *p = malloc(size);
  92. #else
  93. char *xmalloc(size)        /* think this is correct for K&R C */
  94. unsigned int size;
  95. {
  96.     char *p = malloc(size);
  97. #endif
  98.     if (p)
  99.     return p;
  100.     fprintf(stderr, "Malloc failed\n");
  101.     exit(1);
  102.     return NULL;        /* HBB 980317: kill superfluous warnings */
  103. }
  104.  
  105. /* scan the file and build a list of line numbers where particular levels are */
  106. void parse(a)
  107. FILE *a;
  108. {
  109.     static char line[MAX_LINE_LEN+1];
  110.     char *c;
  111.     int lineno = 0;
  112.     int lastline = 0;
  113.  
  114.     /* insert a special level 0 listitem
  115.      * this one is the starting point for the table of contents in the html version
  116.      * and the Top-Node of the info version.
  117.      *
  118.      * Added this to support multiple level 1 items.     --SB
  119.      */
  120.     listitems = 1;
  121.     head = (list = (struct LIST *) xmalloc(sizeof(struct LIST)));
  122.     list->prev = NULL;
  123.     list->line = 0;
  124.     list->level = 0;
  125.     /* I would prefer list->string = NULL, but don't know if free(NULL) is OK
  126.      * with all supported plattforms. */
  127.     list->string = (char *) xmalloc(1);
  128.     list->next = NULL;
  129.  
  130.     while (get_line(line, sizeof(line), a)) {
  131.     lineno++;
  132.     if (isdigit((int)line[0])) {    /* start of new section */
  133.         listitems++;
  134.  
  135.         if (list == NULL) {    /* impossible with the new level 0 item */
  136.         head = (list = (struct LIST *) xmalloc(sizeof(struct LIST)));
  137.         list->prev = NULL;
  138.         } else {
  139.         list->next = (struct LIST *) xmalloc(sizeof(struct LIST));
  140.         list->next->prev = list;
  141.         list = list->next;
  142.         list->next = NULL;
  143.         }
  144.  
  145.         list->line = lastline = lineno;
  146.         list->level = line[0] - '0';
  147.         list->string = (char *) xmalloc(strlen(line) + 1);
  148.         c = strtok(&(line[1]), "\n");
  149.         strcpy(list->string, c);
  150.         list->next = NULL;
  151.         if (list->level > maxlevel)
  152.         maxlevel = list->level;
  153.     }
  154.     if (line[0] == '?') {    /* keywords */
  155.         if (keylist == NULL) {
  156.         keyhead = (keylist = (struct LIST *) xmalloc(sizeof(struct LIST)));
  157.         keylist->prev = NULL;
  158.         } else {
  159.         keylist->next = (struct LIST *) xmalloc(sizeof(struct LIST));
  160.         keylist->next->prev = keylist;
  161.         keylist = keylist->next;
  162.         }
  163.  
  164.         keylist->line = lastline;
  165.         keylist->level = list->level;
  166.         c = strtok(&(line[1]), "\n");
  167.         if (c == NULL || *c == '\0')
  168.         c = list->string;
  169.         keylist->string = (char *) malloc(strlen(c) + 1);
  170.         strcpy(keylist->string, c);
  171.         keylist->next = NULL;
  172.     }
  173.     }
  174.     rewind(a);
  175. }
  176.  
  177. /* look up a topic in text reference */
  178. /*
  179.  * Original version from doc2rtf (|| ipf || html) scanned keylist before list.
  180.  * This way we get a reference to `plot` for the topic `splot` instead
  181.  * of one to `splot`. Switched the search order -SB.
  182.  */
  183. struct LIST *
  184.  lookup(s)
  185. char *s;
  186. {
  187.     char *c;
  188.     char tokstr[MAX_LINE_LEN+1];
  189.     char *match;
  190.     int l;
  191.  
  192.     strcpy(tokstr, s);
  193.  
  194.     /* first try titles */
  195.     match = strtok(tokstr, " \n\t");
  196.     if (match == NULL) {
  197.     fprintf(stderr, "Error in lookup(\"%s\")\n", s);
  198.  
  199.     /* there should a line number, but it is local to parse()  */
  200.     fprintf(stderr, "Possible missing link character (`) near above line number\n");
  201.     exit(3);
  202.     }
  203.     l = 0;            /* level */
  204.  
  205.     list = head;
  206.     while (list != NULL) {
  207.     c = list->string;
  208.     while (isspace((int)(*c)))
  209.         c++;
  210.     if (!strcmp(match, c)) {
  211.         l = list->level;
  212.         match = strtok(NULL, "\n\t ");
  213.         if (match == NULL) {
  214.         return (list);
  215.         }
  216.     }
  217.     if (l > list->level)
  218.         break;
  219.     list = list->next;
  220.     }
  221.  
  222.     /* then try the ? keyword entries */
  223.     keylist = keyhead;
  224.     while (keylist != NULL) {
  225.     c = keylist->string;
  226.     while (isspace((int)(*c)))
  227.         c++;
  228.     if (!strcmp(s, c))
  229.         return (keylist);
  230.     keylist = keylist->next;
  231.     }
  232.  
  233.     return (NULL);
  234. }
  235.  
  236. /*
  237.  * find title-entry for keyword-entry
  238.  */
  239. struct LIST *lkup_by_number(line)
  240. int line;
  241. {
  242.     struct LIST *run = head;
  243.  
  244.     while (run->next && run->next->line <= line)
  245.     run = run->next;
  246.  
  247.     if (run->next)
  248.     return run;
  249.     else
  250.     return NULL;
  251. }
  252.  
  253. /*
  254.  * free the whole list (I never trust the OS -SB)
  255.  */
  256. void list_free __PROTO((void))
  257. {
  258.     struct LIST *run;
  259.  
  260.     for (run = head; run->next; run = run->next);
  261.     for (run = run->prev; run; run = run->prev) {
  262.     free(run->next->string);
  263.     free(run->next);
  264.     }
  265.     free(head->string);
  266.     free(head);
  267.  
  268.     for (run = keyhead; run->next; run = run->next);
  269.     for (run = run->prev; run; run = run->prev) {
  270.     free(run->next->string);
  271.     free(run->next);
  272.     }
  273.     free(keyhead->string);
  274.     free(keyhead);
  275. }
  276.  
  277.  
  278. /* search through the list to find any references */
  279. /* 
  280.  * writes a menu of all subtopics of the topic located at l
  281.  * format must contain %s for the title of the subtopic and may contain
  282.  * a %d for the line number of the subtopic (used by doc2html and doc2rtf
  283.  * The whole menu is preceeded by start and gets the trailer end 
  284.  */
  285. void refs(l, f, start, end, format)
  286. int l;
  287. FILE *f;
  288. char *start, *end, *format;
  289. {
  290.     int curlevel, i;
  291.     char *c;
  292.     int inlist = FALSE;
  293.  
  294.     /* find current line */
  295.     list = head;
  296.     while (list->line != l)
  297.     list = list->next;
  298.     curlevel = list->level;
  299.     list = list->next;        /* look at next element before going on */
  300.  
  301.     if (start != NULL && list != NULL) {    /* don't wrie start if there's no menue at all */
  302.     inlist = TRUE;
  303.     fprintf(f, "%s", start);
  304.     }
  305.     while (list != NULL) {
  306.     /* we are onto the next topic so stop */
  307.     if (list->level == curlevel)
  308.         break;
  309.     /* these are the next topics down the list */
  310.     if (list->level == curlevel + 1) {
  311.         c = list->string;
  312.         while (isspace((int)(*c)))
  313.         c++;        /* strip leading whitespace */
  314.  
  315.         if (format != NULL) {
  316.         for (i = 0; format[i] != '%' && format[i] != '\0'; i++);
  317.         if (format[i] != '\0') {
  318.             if (format[i + 1] == 'd') {
  319.             /* line number has to be printed first */
  320.             fprintf(f, format, list->line, c);
  321.             }
  322.             else {
  323.             ++i;
  324.             for (; format[i] != '%' && format[i] != '\0'; i++);
  325.             if (format[i] != '\0')    /* line number is second */
  326.                 fprintf(f, format, c, list->line);
  327.             else    /* no line number at all */
  328.                 fprintf(f, format, c);
  329.             }
  330.         }
  331.         }
  332.     }
  333.     list = list->next;
  334.     }
  335.     if (inlist && end)        /* trailer */
  336.     fprintf(f, "%s", end);
  337. }
  338.